import os
import errno 
import time
import inspect
import socket
import uuid
import threadpool
import re

from rpyc import Service
from rpyc.utils.server import ThreadedServer

from daemon import Daemon
from remotecopy_log import Log
from utils import Exp, _dmsg, _dwarn, _derror, \
    etchosts_update, cpu_usage, _exec_shell, _exec_pipe, \
    mutil_exec, _get_value, _human_unreadable, _human_readable, \
    _exec_pipe1, _exec_remote1, _lock_file, _exec_system, _put_remote

import rpyc_handle as handle

class RpycSrv(Daemon):
    def __init__(self, conf, home, foreground=False):
        if not os.path.exists(os.path.join(home, 'log')):
            os.mkdir(os.path.join(home, 'log'))

        self.log = Log(os.path.join(home, 'log/remotecopy_server.log'), foreground)
        self.conf = conf
        self.home = home
        self.foreground = foreground

        handle.glo_foreground = self.foreground
        handle.glo_conf = self.conf
        handle.glo_home = self.home

        pidfile = '/var/run/fusionstack_rpyc_server.lock'
        super(RpycSrv, self).__init__(pidfile, name='rpyc_srv')

    def check_port(self, ip, port):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            s.connect((ip,int(port)))
            s.shutdown(2)
            return True
        except:
            return False

    def listen(self):
        if 'listen' not in handle.glo_conf:
            self.log._dwarn("listen port not found in server config")
            return
        port = handle.glo_conf['listen']
        if self.check_port("127.0.0.1", port):
            raise Exp(errno.EADDRINUSE, "start server failed, listen port is used by other services")
        if (self.foreground):
            self.run()
        else:
            self.start()

    def run(self):
        port = handle.glo_conf['listen']
        self.log._dinfo("========server listen:%d" % port)

        try:
            s = ThreadedServer(handle.RpycSrvImpl, port=port)
            s.start()
        except Exception, e:
            if (self.foreground):
                self.log._dinfo("listen:%d fail:%s" % (port, e))
            else:
                self.log._derror(e)

    def stop(self):
        self.log._dinfo("server stopped")
        super(RpycSrv, self).stop()

    def __file_write(self, stat_path, file, context):
        fd = open("%s/%s" % (stat_path, file), 'wb')
        fd.write(str(context))
        fd.close()

    def __file_read(self, stat_path, file):
        try:
            fd = open("%s/%s" % (stat_path, file), 'rb')
            context = fd.read()
            fd.close()

            return context
        except:
            return None

    def __stat_vol_left(self, path_name, chknum):
        count = 0
        for i in range(0, int(chknum)):
            status = self.__file_read(path_name, i)
            if status != 'finish':
                count += 1
        return count

    def __stat_vol__(self, path_name):
        status = self.__file_read(path_name, 'status')
        chknum = self.__file_read(path_name, 'chknum')
        vol = self.__file_read(path_name, 'volume')
        if chknum is not None:
            left = self.__stat_vol_left(path_name, chknum)
        else:
            left = None
        print '        vol:', vol
        print '        status:', status
        print '        chunk: %s/%s' %(left, chknum)

    def __stat_vol(self, path_name):
        list = os.listdir(path_name)

        if len(list) == 0:
            print "No vol found"
            return

        for i in list:
            print "    name:", i
            path = os.path.join(path_name, i)
            self.__stat_vol__(path)

    def __stat_host(self, path_name):
        list = os.listdir(path_name)

        if len(list) == 0:
            print "No client found"
            return

        for i in list:
            m = re.match('\w{8}-\w{4}-\w{4}-\w{4}-\w{12}', i)
            if m is None:
                continue

            print "host:", i
            path = os.path.join(path_name, i)
            self.__stat_vol(path)

    def stat(self, foreground):
        if not super(RpycSrv, self).stat() and not foreground:
            raise Exp(errno.EPERM, "process not running")

        path_name = "%s/stat/" % (self.home)
        if not os.path.exists(path_name):
            os.mkdir(path_name)
        self.__stat_host(path_name)
